// Copyright (C) 1953-2023 NUDT
// Verilog module name - delay_management
// Version: V4.3.0.20230314
// Created:
//         by - fenglin 
//         at - 3.2023
////////////////////////////////////////////////////////////////////////////
// Description:
//          
///////////////////////////////////////////////////////////////////////////

`timescale 1ns/1ps
 
module delay_management #(parameter delay_cycles = 6'd40)
(
        i_clk                ,
        i_rst_n              ,
        
        i_desp_wr            ,
        iv_desp              ,
        //iv_st_inject_dbufid  ,
        
        o_desp_wr            ,
        ov_desp               
        //ov_st_inject_dbufid 
    );

// I/O
// clk & rst
input                   i_clk;
input                   i_rst_n;
//input
(*MARK_DEBUG="true"*)input       [16:0]      iv_desp;
//(*MARK_DEBUG="true"*)input       [4:0]       iv_st_inject_dbufid;
(*MARK_DEBUG="true"*)input                   i_desp_wr;

output  reg             o_desp_wr;
output  reg [16:0]      ov_desp;
//output  reg [4:0]       ov_st_inject_dbufid;
//temp ov_descriptor and ov_pkt for discarding pkt while the fifo_used_findows is over the threshold 
//internal wire&reg
(*MARK_DEBUG="true"*)reg         [5:0]  rv_cycle_cnt;
(*MARK_DEBUG="true"*)reg         [1:0]  delay_management_state;
localparam  idle_s         = 2'b00,
            delay_s        = 2'b01;
        
always@(posedge i_clk or negedge i_rst_n)
    if(!i_rst_n) begin
        o_desp_wr             <= 1'b0;
        ov_desp               <= 17'b0;
        //ov_st_inject_dbufid   <= 5'b0;
        
        rv_cycle_cnt          <= 6'b0;
        delay_management_state <= idle_s;
    end
    else begin
        case(delay_management_state)
            idle_s:begin
                rv_cycle_cnt <= 6'b0;
                if(i_desp_wr == 1'b1)begin//when descriptor come,pkt_bufid_wr have been already
                    o_desp_wr             <= 1'b0;
                    ov_desp               <= iv_desp;
                    //ov_st_inject_dbufid   <= iv_st_inject_dbufid;

                    delay_management_state <= delay_s;                    
                end
                else begin
                    o_desp_wr             <= 1'b0;
                    ov_desp               <= 17'b0;
                    //ov_st_inject_dbufid   <= 5'b0;
                    
                    delay_management_state <= idle_s;
                end
            end 
            delay_s:begin               
                rv_cycle_cnt        <= rv_cycle_cnt + 1'b1;
                if(rv_cycle_cnt == delay_cycles)begin
                    o_desp_wr             <= 1'b1;
                    delay_management_state <= idle_s;
                end
                else begin
                    delay_management_state <= delay_s;
                end
            end
            default:begin
                o_desp_wr             <= 1'b0;
                ov_desp               <= 17'b0;
                //ov_st_inject_dbufid   <= 5'b0;
                
                rv_cycle_cnt          <= 6'b0;
                delay_management_state <= idle_s;
           end
        endcase
    end
endmodule